package com.wicket.okrbff.common.util;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.PutObjectRequest;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.page.PageMethod;
import com.wicket.okrbff.common.annotations.LikeFlag;
import com.wicket.okrbff.common.annotations.OrderFlag;
import com.wicket.okrbff.common.annotations.RangeType;
import com.wicket.okrbff.common.annotations.TreeType;
import com.wicket.okrbff.common.baseinfo.AuthContext;
import com.wicket.okrbff.common.baseinfo.BaseInfoDO;
import com.wicket.okrbff.common.baseinfo.BaseInfoHolder;
import com.wicket.okrbff.common.domain.redis.*;
import com.wicket.okrbff.common.dto.*;
import com.wicket.okrbff.common.exception.BizException;
import com.wicket.okrbff.common.mq.MsgInfo;
import com.wicket.okrbff.common.ro.OkrResult;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import net.sourceforge.pinyin4j.PinyinHelper;
import org.apache.commons.lang3.StringUtils;
import sun.misc.BASE64Decoder;

import java.io.*;
import java.lang.reflect.Field;
import java.math.BigInteger;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Date;
import java.util.concurrent.Callable;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.FutureTask;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static cn.com.antcloud.api.common.GwSigns.urlEncode;

import static cn.hutool.core.util.CharUtil.UNDERLINE;


/**
 * @author ：CHS
 * @since 2022/2/16 14:11
 *
 *
 * @version 1.0
 */
public class CommonFunctionHelper {

    private static Map<String,String> configInfo = new HashMap<>();

    private static RedisUtil redisUtil;

    private static String secStr;

    private static String filePath;

    private static SnowflakeIdWorker uidGen = new SnowflakeIdWorker(2, 2);

    public static String autoGen(String prefix) {
        return prefix + System.currentTimeMillis();
    }

    public static MsgInfo extractMsg(String msg) {
        return new MsgInfo();
    }

    public static void merageObject(Object newObject, Object updateInfo) {

    }

    public static void setRedisUtil(RedisUtil data){
        redisUtil = data;
    }

    public static void setFilePath(String data){
        filePath = data;
    }

    public static void setSecStr(String data){
        secStr = data;
    }

    public static String getSecStr(){
        return secStr;
    }

    public static String humpToUnderline(String str) {
        String regex = "([A-Z])";
        Matcher matcher = Pattern.compile(regex).matcher(str);
        while (matcher.find()) {
            String target = matcher.group();
            str = str.replaceAll(target, "_" + target.toLowerCase());
        }
        return str;
    }

    public static void setBaseInfoToLocal(BaseInfoDO data) {
        AuthContext context = new AuthContext();
        context.setBaseInfo(data);
        BaseInfoHolder.contextHolder.set(context);
    }

    public static BaseInfoDO getBaseInfoFromLocal() {
        return BaseInfoHolder.contextHolder.get().getBaseInfo();
    }

    public static BaseInfoDO getBaseInfoFromCache() {
        return new BaseInfoDO();
    }

    public static void setBaseInfoToCache(BaseInfoDO data) {

    }

    public static List<Map<String,String>> getDbData(String tableName,Map<String,String> filter) {


        String dbAddress = configInfo.get("security.db.address");
        String dbAccount = configInfo.get("security.db.account");
        String dbPassword = configInfo.get("security.db.password");

        Connection conn = null;
        Statement stmt = null;
        try {
//            Class.forName("com.mysql.jdbc.Driver");
            String url = dbAddress;
            String username = dbAccount;
            String password = dbPassword;
            conn = DriverManager.getConnection(url, username, password);
            stmt = conn.createStatement();

            StringBuilder sb = new StringBuilder();
            for (Map.Entry<String, String> entry : filter.entrySet()) {
                if (sb.length() > 0) {
                    sb.append(" AND ");
                }
                sb.append(entry.getKey()).append("=").append("'").append(entry.getValue()).append("'");
            }

            String sql = "SELECT * FROM " + tableName + " where " + sb.toString();

            ResultSet rs = stmt.executeQuery(sql);
            List<Map<String,String>> result = new ArrayList<>();
            ResultSetMetaData metaData = rs.getMetaData();
            int columnCount = metaData.getColumnCount();

            while (rs.next()) {
                Map<String,String> row = new HashMap<>();
                for (int i = 1; i <= columnCount; i++) {
                    String columnName = metaData.getColumnName(i);
                    String columnValue = rs.getString(i);
                    row.put(columnName, columnValue);
                }
                result.add(row);
            }
            return result;
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }finally {

            if(stmt!=null){
                try {
                    stmt.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }

            if(conn!=null){
                try {
                    conn.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
        }
        return new ArrayList<>();

    }

    public static JSONObject getLicenseData(String type){
        String data = getSecStr();
        if(data==null || data.isEmpty()){
            return null;
        }
        //data = "{\"branchName\":\"新数质测试\",\"info\":{\"111\":{\"applexName\":\"111\",\"authorizationEndTime\":\"111\",\"authorizationId\":\"777\",\"authorizationName\":\"新数质证书\",\"authorizationNum\":\"111\",\"authorizationObjectId\":\"111\",\"authorizationObjectType\":\"111\",\"authorizationSchemeId\":\"111\",\"authorizationSpaceId\":\"111\",\"authorizationStartTime\":\"111\",\"authorizationUnit\":\"111\",\"deployTypeCode\":\"111\",\"dnsAddresses\":\"111\",\"ipAddresses\":\"111\",\"isDeploymentEnabled\":\"111\",\"isMainAuthorization\":\"111\",\"schOpenRecordCode\":\"111\",\"schOpenRecordId\":\"111\",\"schemeAuthorizationType\":\"111\",\"serverMacCode\":\"111\",\"spaceShortName\":\"111\"},\"222\":{\"applexName\":\"222\",\"authorizationEndTime\":\"222\",\"authorizationId\":\"777\",\"authorizationName\":\"新数质证书\",\"authorizationNum\":\"222\",\"authorizationObjectId\":\"222\",\"authorizationObjectType\":\"222\",\"authorizationSchemeId\":\"222\",\"authorizationSpaceId\":\"222\",\"authorizationStartTime\":\"222\",\"authorizationUnit\":\"222\",\"deployTypeCode\":\"222\",\"dnsAddresses\":\"222\",\"ipAddresses\":\"222\",\"isDeploymentEnabled\":\"222\",\"isMainAuthorization\":\"222\",\"schOpenRecordCode\":\"222\",\"schOpenRecordId\":\"222\",\"schemeAuthorizationType\":\"222\",\"serverMacCode\":\"222\",\"spaceShortName\":\"222\"}}}";
        JSONObject jsonObject = JSONObject.parseObject(data);
        JSONObject infoObject = jsonObject.getJSONObject("info");
        JSONObject target = infoObject.getJSONObject(type);
        return target;
    }

    public static String getIp(){
        try {
            InetAddress addr = InetAddress.getLocalHost();
            String ip = addr.getHostAddress();
            return ip;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String getMac(){
        String retMac = "";
        try {
            InetAddress address = InetAddress.getLocalHost();
            NetworkInterface ni = NetworkInterface.getByInetAddress(address);
            byte[] mac = ni.getHardwareAddress();
            if (mac != null) {
                System.out.print("MAC address: ");
                for (int i = 0; i < mac.length; i++) {
                    retMac = retMac + String.format("%02X%s", mac[i], (i < mac.length - 1) ? "-" : "");
                }
            } else {
                System.out.println("MAC address not found.");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return retMac;
    }

    public static Date getSpecTime() {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd 'at' HH:mm:ss z");
        Date date = new Date(System.currentTimeMillis());
        return date;
    }

    public static Page<?> startPage(int pageNum, int pageSize) {
        if (pageNum == 0 || pageNum < 0) {
            pageNum = 1;
        }
        if (pageSize == 0 || pageSize < 0) {
            pageSize = 1000;
        }
        Page<?> page = PageMethod.startPage(pageNum, pageSize);
        return page;
    }

    public static void checkCode(String code) {
        if (code.equals("-1")) {
            throw new BizException("-1", false);
        }
    }


    private static Object getValue(Object obj, String targetField) {
        try {
            Field[] declaredFields = obj.getClass().getDeclaredFields();
            for (Field field : declaredFields) {
                if (field.getName().equals(targetField)) {
                    field.setAccessible(true);
                    Object value = field.get(obj);
                    return value;
                }

            }
        } catch (Exception e) {

        }

        return null;
    }

    public static String getMD5Str(String str) {
        byte[] digest = null;
        try {
            MessageDigest md5 = MessageDigest.getInstance("md5");
            digest = md5.digest(str.getBytes("utf-8"));
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        //16是表示转换为16进制数
        String md5Str = new BigInteger(1, digest).toString(16);
        return md5Str;
    }

    public static String generateToken() {
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
        return uuid;
    }

    public static void putUserBasicInfoToRedis(RedisUtil redisClient, UserBaseCacheInfoDto baseUserInfo) {
        BaseUserInfoForRedis retData = new BaseUserInfoForRedis();
        retData.setPowerCodeList(new ArrayList<PrivacyInfoForRedis>());
        retData.setRoleList(new ArrayList<RoleInfoForRedis>());
        BeanUtil.copyProperties(baseUserInfo, retData);
        if (baseUserInfo.getFrameworkPrivacyList() == null && baseUserInfo.getPowerAdminList() == null) {
            for (RoleCacheInfoDto role : baseUserInfo.getRoleList()) {
                RoleInfoForRedis roleData = new RoleInfoForRedis();
                BeanUtil.copyProperties(role, roleData);
                retData.getRoleList().add(roleData);
            }

            for (String code : baseUserInfo.getPowerCodeList()) {
                PrivacyInfoForRedis codeData = new PrivacyInfoForRedis();
                BeanUtil.copyProperties(code, codeData);
                retData.getPowerCodeList().add(codeData);
            }
            //无任何权限的普通员工场景
            Object jo = JSONArray.toJSON(retData);
            redisClient.set("userbase-" + retData.getOriginalRoleMemberId(), jo.toString());
            return;
        } else if (baseUserInfo.getFrameworkPrivacyList() != null && baseUserInfo.getPowerAdminList() == null) {
            //有权限列表的普通员工场景
            for (PrivacyCacheInfoDto privacyInfo : baseUserInfo.getFrameworkPrivacyList()) {
                for (RoleInfoForRedis role : retData.getRoleList()) {
                    if (role.getRoleId() == privacyInfo.getAllocationObjectId()) {
                        if (role.getPowerCodeList() == null)
                            role.setPowerCodeList(new ArrayList<PrivacyInfoForRedis>());
                        PrivacyInfoForRedis privacyElm = new PrivacyInfoForRedis();
                        privacyElm.setPrivacyCode(privacyInfo.getPrivacyCode());
                        role.getPowerCodeList().add(privacyElm);
                    }
                }
            }
            Object jo = JSONArray.toJSON(retData);
            redisClient.set("userbase-" + retData.getOriginalRoleMemberId(), jo.toString());
            return;
        } else if (baseUserInfo.getPowerAdminList() != null && baseUserInfo.getFrameworkPrivacyList() == null) {
            //有权限列表的管理员场景
            for (String code : baseUserInfo.getPowerAdminList()) {
                PrivacyInfoForRedis privacyElm = new PrivacyInfoForRedis();
                privacyElm.setPrivacyCode(code);
                retData.getPowerCodeList().add(privacyElm);
            }
            Object jo = JSONArray.toJSON(retData);
            redisClient.set("userbase-" + retData.getOriginalRoleMemberId(), jo.toString());
            return;
        }
        throw new BizException("-1", "基础用户信息异常", false);
    }

    public static void putUserIrInfoToRedis(RedisUtil redisClient, UserIndCacheInfoDto indUserInfo) {
        UserIndInfoForRedis retData = new UserIndInfoForRedis();
        retData.setUserIndList(new ArrayList<UserIndElmInfoForRedis>());
        for (OrgCacheInfoDto oneElm : indUserInfo.getOrgInductionRecordList()) {
            UserIndElmInfoForRedis retElm = new UserIndElmInfoForRedis();
            BeanUtil.copyProperties(oneElm, retElm);
            if (retElm.getPowerCodeList() == null) retElm.setPowerCodeList(new ArrayList<PrivacyInfoForRedis>());

            //部门权限分配
            for (TributPowerDeptCacheInfoDto deptPrivacyElm : indUserInfo.getTributPowerDeptPositionList()) {
                if (deptPrivacyElm.getAllocationObjectId() == retElm.getOrganizationId()) {
                    PrivacyInfoForRedis privacyElm = new PrivacyInfoForRedis();
                    privacyElm.setPrivacyCode(deptPrivacyElm.getPrivacyCode());
                    retElm.getPowerCodeList().add(privacyElm);
                }
            }

            //职务权限分配
            for (TributPowerPositionCacheInfoDto positionPrivacyElm : indUserInfo.getTributPowerPositiontList()) {
                if (positionPrivacyElm.getAllocationObjectId() == retElm.getPositionId()) {
                    PrivacyInfoForRedis privacyElm = new PrivacyInfoForRedis();
                    privacyElm.setPrivacyCode(positionPrivacyElm.getPrivacyCode());
                    retElm.getPowerCodeList().add(privacyElm);
                }
            }

            //就职记录权限分配
            for (TributPowerInductionCacheInfoDto indPrivacyElm : indUserInfo.getTributPowerInductionRecordList()) {
                if (indPrivacyElm.getAllocationObjectId() == retElm.getPositionId()) {
                    PrivacyInfoForRedis privacyElm = new PrivacyInfoForRedis();
                    privacyElm.setPrivacyCode(indPrivacyElm.getPrivacyCode());
                    retElm.getPowerCodeList().add(privacyElm);
                }
            }

            //权限分配角色
            for (TributPowerRoleCacheInfoDto rolePrivacyElm : indUserInfo.getTributPowerRoleList()) {
                if (rolePrivacyElm.getPositionRoleCode() == retElm.getPositionRoleCode()) {
                    PrivacyInfoForRedis privacyElm = new PrivacyInfoForRedis();
                    privacyElm.setPrivacyCode(rolePrivacyElm.getPrivacyCode());
                    retElm.getPowerCodeList().add(privacyElm);
                }
            }

            retData.getUserIndList().add(retElm);
        }
    }

    public static void putPublicInfoToRedis(RedisUtil redisClient, PublicCacheInfoDto userInfo) {
        try {
            PublicInfoForRedis info = BeanUtil.toBean(userInfo, PublicInfoForRedis.class);
            Object jo = JSONArray.toJSON(info);
            redisClient.set("token-" + info.getOriginalRoleMemberId(), userInfo.getToken());
            redisClient.set(userInfo.getToken(), jo.toString());
        } catch (Exception ex) {
            System.out.println(ex);
        }

    }

    public static void putSpaceInfoToRedis(RedisUtil redisClient, SpaceInfoForRedis spaceInfo) {
        Object jo = JSONArray.toJSON(spaceInfo);
        redisClient.set(spaceInfo.getSpaceId(), jo.toString());
    }

    public static PublicCacheInfoDto getPublicInfoFromRedis(RedisUtil redisClient, String token) {
        String pubInfo = (String) redisClient.get("登录令牌" + ":" + token);
        PublicCacheInfoDto retData = JSONObject.parseObject(pubInfo, PublicCacheInfoDto.class);
        return retData;
    }


    public static SpaceInfoForRedis getSpaceInfoFromRedis(RedisUtil redisClient, String spaceId) {
        String str = (String) redisClient.get(spaceId);
        SpaceInfoForRedis retData = JSONObject.parseObject(str, SpaceInfoForRedis.class);
        if (retData != null && retData.getOrgList() == null) {
            retData.setOrgList(new ArrayList<OrgInfoForRedis>());
        }
        return retData;
    }

    public static void changePublicInfoFromRedis(RedisUtil redisClient, String indId) {
        String token = (String) redisClient.get("token-" + getBaseInfoFromLocal().getSpecOriginalRoleMemberId());
        PublicCacheInfoDto info = getPublicInfoFromRedis(redisClient, token);
        if (info == null) {
            return;
        }
        info.setInductionRecordId(indId);
        info.setToken(token);
        putPublicInfoToRedis(redisClient, info);
    }

    public static Boolean calculationMethod(Long lastLockoutTime, Long thresholdValue) {
        return lastLockoutTime >= thresholdValue;
    }

    public static void clearBaseInfo() {
        BaseInfoHolder.contextHolder.remove();
    }


    public static Date getFutureTime() {
        return new Date();
    }

    public static Date getCurrentTime() {
        return new Date();
    }

    public static String str2Md5(String inStr) {
        return inStr;
        /*
        char[] a = inStr.toCharArray();
        for (int i = 0; i < a.length; i++) {
            a[i] = (char) (a[i] ^ 't');
        }
        String s = new String(a);
        return s;

         */

    }

    public static String getUid() {

        return String.valueOf(uidGen.nextId());
    }

    public static String Md52Str(String inStr) {
        return str2Md5(str2Md5(inStr));

    }

    public static String getEquipMent() {
        return "PC";
    }

    public static String constructRedirectUrl(String casServerLoginUrl, String serviceParameterName, String serviceUrl, boolean renew, boolean gateway) {
        return casServerLoginUrl + (casServerLoginUrl.contains("?") ? "&" : "?") + serviceParameterName + "=" + urlEncode(serviceUrl) + (renew ? "&renew=true" : "") + (gateway ? "&gateway=true" : "");
    }

    public static String constructRedirectUrl(String casServerLoginUrl, String serviceParameterName, String serviceUrl) {
        return casServerLoginUrl + (casServerLoginUrl.contains("?") ? "&" : "?") + serviceParameterName + "=" + urlEncode(serviceUrl);
    }

    public static String getSessionUrl() {
        return getBaseInfoFromLocal().getSpecLoginIp();
    }

    public static String getLogInIp() {
        return getBaseInfoFromLocal().getSpecLoginIp();
    }

    public static void asynExcute(Callable<String> call) {
        // 创建一个 FutureTask（doOneThing 任务）
        FutureTask<String> futureTask = new FutureTask<>(call);
        // 使用线程池执行 doOneThing 任务
        ForkJoinPool.commonPool().submit(futureTask);
    }

    public static Boolean checkCaptchaValid(VertifyReqDto req) {
        return true;
    }

    public static void clearTokenFromRedis(RedisUtil redisClient, String originalRoleMemberId) {
        String token = (String) redisClient.get("token-" + originalRoleMemberId);
        if (token == null || token.isEmpty()) return;
        redisClient.delete(token);
        redisClient.delete("token-" + originalRoleMemberId);
    }

    public static void clearSpaceInfoFromRedis(RedisUtil redisClient, SpaceInfoToRedisListReqDto req) {
        for (String spaceId : req.getSpaceInfoToRedisList()) {
            redisClient.delete(spaceId);
        }
    }

    public static void clearUserInfoFromRedis(RedisUtil redisClient, String originalRoleMemberId) {
        if (originalRoleMemberId == null || originalRoleMemberId.isEmpty()) return;
        redisClient.delete("userbase-" + originalRoleMemberId);
        redisClient.delete("inductionInfo-" + originalRoleMemberId);
    }

    public static void batchClearUserInfoFromRedis(RedisUtil redisClient, List<String> beginMemberList) {
        if (beginMemberList == null || beginMemberList.isEmpty()) return;
        for (String member : beginMemberList) {
            redisClient.delete("userbase-" + member);
            redisClient.delete("inductionInfo-" + member);
        }
    }

    public static void batchClearTokenFromRedis(RedisUtil redisClient, List<String> beginMemberList) {
        if (beginMemberList == null || beginMemberList.isEmpty()) return;
        for (String member : beginMemberList) {
            clearTokenFromRedis(redisClient, member);
        }
    }

    public static String firstChar(String srcData) {
        StringBuilder convert = new StringBuilder();
        if (StringUtils.isBlank(srcData)) {
            return "";
        }
        char word = srcData.charAt(0);
        String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(word);
        if (pinyinArray != null) {
            convert.append(pinyinArray[0].charAt(0));
        } else {
            convert.append(word);
        }
        return convert.toString().toUpperCase();
    }

    public static Object extractResult(OkrResult<?> result) {
        if (!result.isSuccess()) {
            throw new BizException(result.getErrCode(), result.getMessage(), false);
        } else {
            return result.getData();
        }
    }

    public static String getFilePath(String src) {
        if (src.startsWith("http")) return src;
        JSONObject configInfo = (JSONObject)redisUtil.get("平台软件配置" + ":" + "PLATFORM_OM_CONF");
        String path = configInfo.getString("fileDisplayRootPath");
        if (!src.startsWith("/")) src = "/" + src;
        if (path.endsWith("/")) {
            path = path.substring(0, path.lastIndexOf("/"));
        }
        return path + src;

    }

    public static String getUrlPath(String src) {
        if (src.indexOf("http://") == -1 && src.indexOf("https://") == -1) {
            JSONObject configInfo = (JSONObject)redisUtil.get("平台软件配置" + ":" + "PLATFORM_OM_CONF");
            String path = configInfo.getString("fileDisplayRootPath");
            if (!path.endsWith("/")) path = path + "/";
            if (src.indexOf("/") == 0) {
                src = src.substring(1);
            }
            return path + src;
        } else {
            return src;
        }

    }
///----------------------------------------


    /**
     * 计算数据条数
     *
     * @param obj
     * @return
     */
    public static Integer getDataCount(Object obj) {
        if (obj == null) {
            return null;
        }
        int count;
        List list = new ArrayList();
        if (obj instanceof List) {
            //for (Object o:(List)obj) {
            //list.add(o);
            list = (List) obj;
            return list.size();
        }


        return count = 1;

    }


    /**
     * 获取初始标识
     *
     * @param sign:标识
     */
    public static String getInitCode(String sign) {
        if (sign != null) {
            return sign + "1000";
        }
        return null;
    }

    /**
     * 获取后续标识
     *
     * @param sign
     * @return
     */
    public static String getNextCode(List<String> sign) {
        if (sign.isEmpty() || sign == null) {
            return null;
        }
        String max = Collections.max(sign);
        Integer n = Integer.valueOf(max) + 1;
        String code = String.valueOf(n);
        return code;

    }


    /**
     * 周期类型排序规则
     *
     * @param startTime：开始时间
     * @param endTime：结束时间
     * @return
     */
    public static Long getDateTimeOrderNum(Date startTime, Date endTime) {
        if (startTime != null && endTime != null) {
            long sTime = startTime.getTime();

            long eTime = endTime.getTime();

            return eTime * 100 + (eTime - sTime);
        }
        return null;
    }


    /**
     * 找N级标识
     *
     * @param code:当前数据的标识
     * @param cLevel:当前数据的层级
     * @param fLevel:指定的层级
     */
    public static String findLevelCode(String code, String cLevel, String fLevel) {
        if (code != null && cLevel != null && fLevel != null) {
            int a = Integer.valueOf(cLevel);
            int b = Integer.valueOf(fLevel);
            int c = (a - b) * 4;
            return code.substring(0, code.length() - c);
        }
        return null;
    }


    /**
     * 获取用户缓存角色列表
     *
     * @param token:token
     * @return
     */
    public static List getUserRoleListFromRedis(RedisUtil redisClient, String token) {
        if (redisClient != null && token != null) {
            PublicCacheInfoDto publicInfoFromRedis = getPublicInfoFromRedis(redisClient, token);
            String originalRoleMemberId = publicInfoFromRedis.getOriginalRoleMemberId();
            BaseUserInfoForRedis retData = getUserBasicInfoFromRedis(redisClient, originalRoleMemberId);
            List<RoleInfoForRedis> roleList = retData.getRoleList();
            return roleList;
        }
        return null;
    }

    /**
     * 获取用户全部权限
     *
     * @param redisClient
     * @return
     */
    public static List<PrivacyInfoForRedis> getUserAllPower(RedisUtil redisClient, String originalRoleMemberId) {
        if (redisClient != null) {
            BaseUserInfoForRedis retData = getUserBasicInfoFromRedis(redisClient, originalRoleMemberId);
            List<RoleInfoForRedis> roleList = retData.getRoleList();
            List list = new ArrayList<>();
            List listCode = new ArrayList<>();
            for (int i = 0; i < roleList.size(); i++) {
                RoleInfoForRedis roleInfoForRedis = roleList.get(i);
                List<PrivacyInfoForRedis> powerCodeList = roleInfoForRedis.getPowerCodeList();
                for (PrivacyInfoForRedis privacyInfoForRedis : powerCodeList) {
                    if (!listCode.contains(privacyInfoForRedis.getPrivacyCode())) {
                        listCode.add(privacyInfoForRedis.getPrivacyCode());
                        list.add(privacyInfoForRedis);
                    }
                }
            }
            List<PrivacyInfoForRedis> powerCodeList = retData.getPowerCodeList();
            for (PrivacyInfoForRedis privacyInfoForRedis : powerCodeList) {
                if (!listCode.contains(privacyInfoForRedis.getPrivacyCode())) {
                    listCode.add(privacyInfoForRedis.getPrivacyCode());
                    list.add(privacyInfoForRedis);
                }
            }
            return list;
        }
        return null;
    }

    /**
     * 生成随机数
     *
     * @param n:几位数
     * @return
     */
    public static String generateRandomNum(Integer n) {
        if (n != 0) {
            String code = "";
            Random r = new Random();
            for (int i = 0; i < n; i++) {
                code += r.nextInt(10);
            }
            return code;
        }
        return null;
    }


    /**
     * 存缓存
     *
     * @param key
     * @param value
     */
    public static void putKvToRedis(String key, String value) {
        if (key != null && value != null) {
            RedisUtil redisUtil = new RedisUtil();
            redisUtil.set(key, value);
        }
    }

    /**
     * 列转行
     *
     * @param listData
     */
    public static List<Map<String, Object>> columnToRow(List<ColumnDto> listData) {
        String keyId = "id";
        if (listData == null) {
            return null;// new ArrayList<Map<String, Object>>();
        }
        List<String> listId = new ArrayList<String>();
        for (ColumnDto a : listData) {
            if (!listId.contains(a.getId())) {
                listId.add(a.getId());
            }
        }
        List<Map<String, Object>> listMap = new ArrayList<Map<String, Object>>();
        for (String id : listId) {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put(keyId, id);
            for (ColumnDto a : listData) {
                if (a.getId().equals(id)) {
                    String key = a.getKey().toLowerCase();
                    int len = key.length();
                    StringBuilder sb = new StringBuilder(len);
                    for (int i = 0; i < len; i++) {
                        char c = key.charAt(i);
                        if (c == UNDERLINE) {
                            if (++i < len) {
                                sb.append(Character.toUpperCase(key.charAt(i)));
                            }
                        } else {
                            sb.append(c);
                        }
                    }
                    String k = sb.toString();
                    map.put(k, a.getValue());
                }

            }
            listMap.add(map);
        }
        return listMap;

    }

    /**
     * 列转行标识
     *
     * @param listData
     * @param keyId
     * @return
     */
    public static List<Map<String, Object>> columnToRow(List<Map> listData, String keyId) {
        if (listData == null) {
            return null;// new ArrayList<Map<String, Object>>();
        }
        List<String> listId = new ArrayList<String>();
        for (Map<String, Object> a : listData) {
            String id = a.get(keyId) == null ? null : a.get(keyId).toString();
            if (!listId.contains(id) && id != null) {
                listId.add(id);
            }
        }
        List<Map<String, Object>> listMap = new ArrayList<Map<String, Object>>();
        for (String id : listId) {
            Map<String, Object> map = new HashMap<String, Object>();
            //map.put(keyId,id);
            for (Map<String, Object> a : listData) {
                String idvalue = a.get(keyId) == null ? null : a.get(keyId).toString();
                if (idvalue.equals(id)) {
                    Set<String> keys = a.keySet();
                    for (String key : keys) {
                        map.put(key, a.get(key));
                    }
                }
            }
            listMap.add(map);
        }
        return listMap;
    }

    public static List<Map<String, Object>> COLUMN_TO_ROW_CODE(Object listData, String keyId) {
        String str = JSONObject.toJSONString(listData);
        List<Map> listMap = JSONObject.parseArray(str, Map.class);
        return columnToRow(listMap, keyId);
    }



    public static List<TreeNode> buildTree(List<Object> nodeList) {
        Map<String, TreeNode> newMap = new HashMap<>();
        List<TreeNode> result = new ArrayList<>();
        for (Object node : nodeList) {
            TreeNode treeNode = new TreeNode();
            treeNode.setSelf(node);
            newMap.put(getPriId(node), treeNode);
        }
        for (Object node : nodeList) {
            TreeNode parent = newMap.get(getParentId(node));
            if (ObjectUtil.isNotNull(parent)) {
                if (CollUtil.isEmpty(parent.getChildrenList())) {
                    List<TreeNode> ch = new ArrayList<>();
                    ch.add(newMap.get(getPriId(node)));
                    parent.setChildrenList(ch);
                } else {
                    List<TreeNode> ch = parent.getChildrenList();
                    ch.add(newMap.get(getPriId(node)));
                }
            } else {
                TreeNode fParent = newMap.get(getFid(node));
                if (ObjectUtil.isNotNull(fParent)) {
                    //子数据集的根节点
                    if (CollUtil.isEmpty(fParent.getChildrenList())) {
                        List<TreeNode> ch = new ArrayList<>();
                        ch.add(newMap.get(getPriId(node)));
                        fParent.setChildrenList(ch);
                    } else {
                        List<TreeNode> ch = fParent.getChildrenList();
                        ch.add(newMap.get(getPriId(node)));
                    }
                } else {
                    //为主数据集的根节点
                    result.add(newMap.get(getPriId(node)));
                }
            }
        }
        return result;
    }

    public static String getParentId(Object node) {
        try {
            Class classzz = node.getClass();
            Field[] declaredFields = classzz.getDeclaredFields();
            for (Field field : declaredFields) {
                field.setAccessible(true);
                TreeType falg = (TreeType) field.getAnnotation(TreeType.class);
                if (falg!=null && falg.value().equals("pid")) {
                    return (String) field.get(node);
                }
            }
        } catch (Exception e) {

        }
        return "-1";
    }

    public static String getPriId(Object node) {
        try {
            Class classzz = node.getClass();
            Field[] declaredFields = classzz.getDeclaredFields();
            for (Field field : declaredFields) {
                field.setAccessible(true);
                TreeType falg = (TreeType) field.getAnnotation(TreeType.class);
                if (falg!=null && falg.value().equals("id")) {
                    return (String) field.get(node);
                }
            }
        } catch (Exception e) {

        }
        return "-1";
    }

    public static String getFid(Object node) {
        try {
            Class classzz = node.getClass();
            Field[] declaredFields = classzz.getDeclaredFields();
            for (Field field : declaredFields) {
                field.setAccessible(true);
                TreeType falg = (TreeType) field.getAnnotation(TreeType.class);
                if (falg!=null && falg.value().equals("fid")) {
                    return (String) field.get(node);
                }
            }
        } catch (Exception e) {

        }
        return "-1";
    }

    public static BaseUserInfoForRedis getUserBasicInfoFromRedis(RedisUtil redisClient, String originalRoleMemberId) {
        String str = (String) redisClient.get("userbase-" + originalRoleMemberId);
        if (str == null || str.isEmpty()) {
            return new BaseUserInfoForRedis();
        }
        BaseUserInfoForRealRedis redisData = JSONObject.parseObject(str, BaseUserInfoForRealRedis.class);
        BaseUserInfoForRedis retData = new BaseUserInfoForRedis();
        BeanUtil.copyProperties(redisData, retData, "birthday");
        SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = null;
        try {
            if (redisData.getBirthday() != null && !redisData.getBirthday().isEmpty()) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String times = sdf.format(Long.valueOf(redisData.getBirthday()));
                date = ft.parse(times);
                retData.setBirthday(date);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return retData;
    }

    public static UserIndInfoForRedis getUserIrInfoFromRedis(RedisUtil redisClient, String originalRoleMemberId) {
        String str = (String) redisClient.get("inductionInfo-" + originalRoleMemberId);
        if (str == null || str.isEmpty()) {
            return new UserIndInfoForRedis();
        }
        UserIndInfoForRedis retData = JSONObject.parseObject(str, UserIndInfoForRedis.class);
        if (retData.getUserIndList() == null) {
            retData.setUserIndList(new ArrayList<>());
        }
        return retData;
    }

    public static void uploadFileToAwazon(String endPoint,String region,String accessKey,String secretKey,String buckName,byte[] fileContent,File file,String filePath){
        BasicAWSCredentials awsCreds = new BasicAWSCredentials(accessKey, secretKey);

        AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
                .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(endPoint, region))
                .withCredentials(new AWSStaticCredentialsProvider(awsCreds))
                .build();

        try {


            if(fileContent!=null){
                // 上传文件
                PutObjectRequest request = new PutObjectRequest(buckName, filePath, new java.io.ByteArrayInputStream(fileContent), null);
                s3Client.putObject(request);

                System.out.println("File uploaded successfully for bytes.");
            }else if(file !=null){
// 上传文件
                PutObjectRequest request = new PutObjectRequest(buckName, filePath, new FileInputStream(file), null);
                s3Client.putObject(request);

                System.out.println("File uploaded successfully for file.");
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static boolean isDecimalPartAllZeros(double value) {
        double integerPart = Math.floor(value); // 获取整数部分
        double decimalPart = value - integerPart; // 获取小数部分
        return decimalPart == 0; // 检查小数部分是否为0
    }

    public static void GenerateImage(String base64Str, String imgFilePath,boolean useOss) {
        if (base64Str == null) {
            return;
        }
        try {
            // Base64解码
            byte[] bytes = Base64.getDecoder().decode(base64Str);
            for (int i = 0; i < bytes.length; ++i) {
                if (bytes[i] < 0) {
                    bytes[i] += 256; // 调整异常数据
                }
            }

            if (useOss) {
                // 使用MinIO OSS上传
                String minioEndpoint = "http://192.168.31.221:9090";
                String minioAccessKey = "KY80gzS3rMyKv9kFC2VP";
                String minioSecretKey = "607sguKZLS6sOzlxIWhfxGqaXC7sQwiHxlarfJT5";
                String bucketName = "upload";
                String objectName = imgFilePath;


                try {
                    MinioClient minioClient = MinioClient.builder()
                            .endpoint(minioEndpoint)
                            .credentials(minioAccessKey, minioSecretKey)
                            .build();
                    minioClient.putObject(
                            PutObjectArgs.builder()
                                    .bucket(bucketName)
                                    .object(objectName)
                                    .stream(new ByteArrayInputStream(bytes), bytes.length, -1)
                                    .build());
                    System.out.println("File uploaded successfully to " + bucketName + "/" + objectName);
                } catch (IOException e) {
                    System.out.println("Error occurred while creating MinioClient: " + e.getMessage());
                }
            } else {
                // 生成jpeg图片
                try (FileOutputStream out = new FileOutputStream(imgFilePath)) {
                    out.write(bytes);
                    out.flush();
                    System.out.println("File saved to " + imgFilePath);
                }
            }
        } catch (Exception e) {
            System.out.println(e);
        }
    }

    public static void buildQueryWrapperLike(QueryWrapper<?> queryWrapper, List<FieldInfo> likeList, Map<String, Object> fieldInfoMap) {
        for (FieldInfo columnInfo : likeList) {
            if (fieldInfoMap.get(columnInfo.getName()) != null) {
                if (columnInfo.getOrderType() == 2L) {
                    queryWrapper.likeRight(columnInfo.getName(), fieldInfoMap.get(columnInfo.getName()));
                } else {
                    queryWrapper.like(columnInfo.getName(), fieldInfoMap.get(columnInfo.getName()));
                }
            }
        }
    }

    public static void buildQueryWrapperEq(QueryWrapper<?> queryWrapper, Map<String, Object> fieldInfo, List<FieldInfo> likeFieldList) {
        Map<String, String> index = new HashMap<>();
        if (likeFieldList != null) {
            for (FieldInfo oneFile : likeFieldList) {
                index.put(oneFile.getName(), oneFile.getName());
            }
        }
        for (Map.Entry<String, Object> columnInfo : fieldInfo.entrySet()) {
            if (!index.containsKey(columnInfo.getKey())) {
                queryWrapper.eq(columnInfo.getKey(), columnInfo.getValue());
            }
        }
    }

    public static void buildQueryWrapperOrder(QueryWrapper<?> queryWrapper, List<FieldInfo> orderList) {
        for (FieldInfo orderColumn : orderList) {
            if (orderColumn.getOrderType() != null && orderColumn.getOrderType() == 1)
                queryWrapper.orderByAsc(orderColumn.getName());
            if (orderColumn.getOrderType() != null && orderColumn.getOrderType() == 2)
                queryWrapper.orderByDesc(orderColumn.getName());
        }
    }

    public static void nbDbWorker(Connection conn, Object param, String cmd, String extInfo) {
        NbDbWoker worker = new NbDbWoker();
        switch (cmd) {
            case "updateSortNumCom":
                worker.updateSortNumCom(conn, param);
                break;
            case "releaseSingleDataCom":
                worker.releaseSingleDataCom(conn, param);
                break;
            case "archiveBatchSingleDataCom":
                worker.archiveBatchSingleDataCom(conn, param);
                break;
            case "deleteSingleDataCom":
                worker.deleteSingleDataCom(conn, param);
                break;
            case "undoArchiveBatchSingleDataCom":
                worker.undoArchiveBatchSingleDataCom(conn, param);
                break;
            case "reviseNotBatchContent":
                worker.reviseNotBatchContent(conn, param);
                break;
            case "undoReviseBatchSingleData":
                worker.undoReviseBatchSingleData(conn, param);
                break;
            case "ADD_NUMERICAL":
                worker.automicAdd(conn, param, extInfo);
                break;
            case "SUBTRACT_NUMERICAL":
                worker.automicsub(conn, param, extInfo);
                break;
        }
    }

    public static void buildTimeRange(QueryWrapper<?> queryWrapper, List<FieldInfo> orderList) {
        for (FieldInfo orderColumn : orderList) {
            if (orderColumn.getOrderType() != null && orderColumn.getOrderType() == 1)
                queryWrapper.orderByAsc(orderColumn.getName());
            if (orderColumn.getOrderType() != null && orderColumn.getOrderType() == 2)
                queryWrapper.orderByDesc(orderColumn.getName());
        }
    }

    public static Map<String, Object> objectToMap(Object obj) throws Exception {
        if (obj == null) {
            return null;
        }
        Map<String, Object> map = new HashMap<String, Object>();
        Field[] declaredFields = obj.getClass().getDeclaredFields();
        for (Field field : declaredFields) {
            field.setAccessible(true);
            Object value = field.get(obj);
            if (value != null && value instanceof String) {
                String tmp = (String) value;
                if (tmp.isEmpty()) value = null;
            }
            if (value != null && !field.getName().equals("serialVersionUID")) {
                map.put(humpToUnderline(field.getName()), value);
            }
        }
        return map;
    }

    public static Map<String, Object> objectToMapForLamBda(Object obj) throws Exception {
        if (obj == null) {
            return null;
        }
        Map<String, Object> map = new HashMap<String, Object>();
        Field[] declaredFields = obj.getClass().getDeclaredFields();
        for (Field field : declaredFields) {
            field.setAccessible(true);
            Object value = field.get(obj);
            if (value != null && value instanceof String) {
                String tmp = (String) value;
                if (tmp.isEmpty()) value = null;
            }
            if (value != null && value instanceof List) {
                value = null;
            }
            if (value != null && !field.getName().equals("serialVersionUID")) {
                map.put(humpToUnderline(field.getName()), value);
            }
        }
        return map;
    }

    public static List<FieldInfo> getOrderList(Class classzz) throws Exception {
        List<FieldInfo> result = new ArrayList<>();
        Field[] declaredFields = classzz.getDeclaredFields();
        for (Field field : declaredFields) {
            field.setAccessible(true);
            OrderFlag falg = (OrderFlag) field.getAnnotation(OrderFlag.class);
            FieldInfo fieldInfo = new FieldInfo();
            fieldInfo.setName(humpToUnderline(field.getName()));
            if (falg != null && falg.orderType().toLowerCase(Locale.ROOT).equals("asc")) fieldInfo.setOrderType(1L);
            if (falg != null && falg.orderType().toLowerCase(Locale.ROOT).equals("desc")) fieldInfo.setOrderType(2L);
            if (fieldInfo.getOrderType() != null) result.add(fieldInfo);
        }
        return result;
    }

    public static List<FieldInfo> getLikeFiled(Class classzz) throws Exception {
        List<FieldInfo> result = new ArrayList<>();
        Field[] declaredFields = classzz.getDeclaredFields();
        for (Field field : declaredFields) {
            field.setAccessible(true);
            LikeFlag falg = (LikeFlag) field.getAnnotation(LikeFlag.class);
            FieldInfo fieldInfo = new FieldInfo();
            fieldInfo.setName(humpToUnderline(field.getName()));
            if (falg != null && falg.likeType().toLowerCase(Locale.ROOT).equals("all")) fieldInfo.setLikeType(1L);
            if (falg != null && falg.likeType().toLowerCase(Locale.ROOT).equals("right")) fieldInfo.setLikeType(2L);
            if (fieldInfo.getLikeType() != null) result.add(fieldInfo);
        }
        return result;
    }

    public static List<FieldInfo> getRangeField(Class classzz) throws Exception {
        List<FieldInfo> result = new ArrayList<>();
        Field[] declaredFields = classzz.getDeclaredFields();
        for (Field field : declaredFields) {
            field.setAccessible(true);
            RangeType falg = (RangeType) field.getAnnotation(RangeType.class);
            FieldInfo fieldInfo = new FieldInfo();
            fieldInfo.setName(humpToUnderline(field.getName()));
            if (falg != null && falg.RangeType().toLowerCase(Locale.ROOT).equals(">=")) {
                fieldInfo.setRangeType(1L);
            }

            if (falg != null && falg.RangeType().toLowerCase(Locale.ROOT).equals(">")) {
                fieldInfo.setRangeType(2L);
            }

            if (falg != null && falg.RangeType().toLowerCase(Locale.ROOT).equals("<=")) {
                fieldInfo.setRangeType(3L);
            }

            if (falg != null && falg.RangeType().toLowerCase(Locale.ROOT).equals("<")) {
                fieldInfo.setRangeType(4L);
            }

            if (fieldInfo.getLikeType() != null) {
                result.add(fieldInfo);
            }
        }
        return result;
    }

    public static void buildQueryWrapperCompare(QueryWrapper<?> queryWrapper, Map<String, Object> fieldInfo, List<FieldInfo> compareFiledList) {
        for (FieldInfo compareFile : compareFiledList) {
            if (compareFile.getRangeType() != null && compareFile.getRangeType() == 1) {
                if (fieldInfo.get(compareFile.getName()) != null) {
                    queryWrapper.ge(compareFile.getName(), fieldInfo.get(compareFile.getName()));
                }
            }
            if (compareFile.getRangeType() != null && compareFile.getRangeType() == 2) {
                if (fieldInfo.get(compareFile.getName()) != null) {
                    queryWrapper.gt(compareFile.getName(), fieldInfo.get(compareFile.getName()));
                }
            }
            if (compareFile.getRangeType() != null && compareFile.getRangeType() == 3) {
                if (fieldInfo.get(compareFile.getName()) != null) {
                    queryWrapper.le(compareFile.getName(), fieldInfo.get(compareFile.getName()));
                }
            }
            if (compareFile.getRangeType() != null && compareFile.getRangeType() == 4) {
                if (fieldInfo.get(compareFile.getName()) != null) {
                    queryWrapper.lt(compareFile.getName(), fieldInfo.get(compareFile.getName()));
                }
            }
        }
    }

    /**
     * 下划线转驼峰
     *
     * @param str 目标字符串
     * @return: java.lang.String
     */
    public static String underlineToHump(String str) {
        str = str.toLowerCase(Locale.ROOT);
        String regex = "_(.)";
        Matcher matcher = Pattern.compile(regex).matcher(str);
        while (matcher.find()) {
            String target = matcher.group(1);
            str = str.replaceAll("_" + target, target.toUpperCase());
        }
        return str;
    }

    public static String getSpecImage(String src,String sizeStr){
        if(src!=null && !src.isEmpty()){
            int dotIndex = src.lastIndexOf('.');
            if (dotIndex == -1) {
                return src; // No extension found.
            }

            return src.substring(0, dotIndex) + sizeStr + src.substring(dotIndex);
        }
        return src;
    }


    public static Map<String, String> getConfigInfo() {
        return configInfo;
    }

    public static void setConfigInfo(Map<String, String> configInfo) {
        CommonFunctionHelper.configInfo = configInfo;
    }
}
